package com.tanhua.dubbo.server.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.tanhua.dubbo.server.config.HuanXinConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 *
 * @ClassName: TokenService
 * @Author:王晨晗
 * @Description: 获取环信token
 * @Date: 2022/01/05/11:06
 */
@Service
@Slf4j
public class TokenService {
    @Autowired
    private HuanXinConfig huanXinConfig;
    @Autowired
    private RedisTemplate<String , String> redisTemplate;

    private static final String REDIS_KEY= "HX_TOKEN";      //环信token在redis中的键

    /**
     * @description 获取环信的token,先从redis中获取,redis中没有, 再从环信接口中获取
     * @return
     */
    public String getToken(){
        //从redis中获取token
        String token = redisTemplate.opsForValue().get(REDIS_KEY);
        //判断token是否为空
        if (StrUtil.isNotEmpty(token)){
            return token;       //
        }
        //访问环信接口,获取token
        return refreshToken();
    }

    /**
     * @description 访问环信接口,获取token
     * @return
     */
    public String refreshToken() {
        //获取环信token的url地址
        String targetUrl = huanXinConfig.getUrl() + huanXinConfig.getOrgName() + "/" + huanXinConfig.getAppName() + "/token";
        //请求消息(参数)
        Map<String , Object> param = new HashMap<>();
        param.put("grant_type" , "client_credentials");
        param.put("client_id" , huanXinConfig.getClientId());
        param.put("client_secret" , huanXinConfig.getClientSecret());

        //发送获取token的请求
        HttpResponse response = HttpRequest.post(targetUrl)     //请求url
                .body(JSONUtil.toJsonStr(param))        //请求参数
                .timeout(20000)     //请求超时时间
                .execute();//执行;

        //判断获取token是否成功
        if (!response.isOk()){
            log.error("刷新token失败~~~");
            return null;    //失败返回null
        }
        //获取响应体内容
        String jsonBody = response.body();
        //解析json成对象
        JSONObject jsonObject = JSONUtil.parseObj(jsonBody);
        //获取token的值
        String token = jsonObject.getStr("access_token");
        //判断token是否为空
        if (StrUtil.isNotEmpty(token)){     //不为空,存入redis中,返回token
            //获取token有效时间
            Long timeout = jsonObject.getLong("expires_in") - 3600;
            //存入redis中,并设置有效时间
            redisTemplate.opsForValue().set(REDIS_KEY , token , timeout , TimeUnit.SECONDS);
            //返回token
            return token;
        }
        //token为空,返回null
        return null;
    }

}
